
/**	
*	
	Doyle Spiral
*/

import ij.ImagePlus;
import ij.plugin.PlugIn;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;

import java.awt.Color;
import java.awt.Font;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.Random; 


import pluginUtils.DoyleCircle;


public class doyle7_ extends ImagePlus implements PlugIn {
	private ImageProcessor primeIP; 
	private int X=2000,Y=2000;
	private Random generator=new Random(); 
	private ArrayList<DoyleCircle> memoire=new ArrayList<DoyleCircle>();
	private ArrayList<DoyleCircle> traites=new ArrayList<DoyleCircle>();
	private ArrayList<DoyleCircle> traces=new ArrayList<DoyleCircle>();
	private int order=0;
	
	private int module=19; 
	
	private double  n=3; //13.0; 
	private double  m=44; //11.0; 
	
	
	private float redColor[]=new float[module]; 
	private float blueColor[]=new float[module];
	private float greenColor[]=new float[module];
	
	private boolean first=true; 
	
	private void drawCircle(DoyleCircle c){
		//if(intersect(c))return; 
		//if(c.getRadius()<0.0001) return; 
		System.out.println(c.getXcenter()*X+" "+c.getYcenter()*X);
		int intX=(int)(c.getXcenter()*X);
		int intY=(int)(c.getYcenter()*Y);
		int intR=(int)(c.getRadius()*X); // X ??
		//primeIP.setColor(new Color(redColor[order%module],greenColor[order%module],blueColor[order%module]));
		/*if(first){
			first=false;
			primeIP.drawOval(intX-intR,intY-intR,intR*2,intR*2);
			primeIP.moveTo(intX-85,intY+20); 
			primeIP.drawString("Origin");
		}
		else*/{
			int rank=Math.abs(c.getBpower())%module; 
			
		primeIP.setColor(new Color(redColor[rank],greenColor[rank],blueColor[rank]));
		/*primeIP.setColor(new Color(generator.nextFloat(),
									generator.nextFloat(),
									generator.nextFloat()));*/
		primeIP.drawOval(intX-intR,intY-intR,intR*2,intR*2);
		//primeIP.drawOval(intX-intR,intY-intR,intR*2,intR*2);
		//primeIP.moveTo(intX-85,intY+20); 
		//primeIP.drawString("("+c.getApower()+","+c.getBpower()+")");
		}
		order++;
	}
	
	

	public void run(String arg) {
		primeIP = new ColorProcessor(X,Y);
		
		double r=0.005; 
		double a=1.12; 
		double b=Math.pow(Math.pow(a,n), 1/m); 
		System.out.println("--->"+b);
		DoyleCircle.setBounds((int)m, (int)n); 
		
		
		System.out.println(Math.pow((1+a)*r,n)+" "+Math.pow((1+b)*r,m)); 
		
		float cseed=0.0f; 
		float step=1.0f/module; 
		for(int i=0;i<module;i++){
			redColor[i]=generator.nextFloat(); 
			blueColor[i]=generator.nextFloat(); 
			greenColor[i]=generator.nextFloat();
			
			/*redColor[i]=0.2f+0.8f*cseed*(1-cseed); 
			blueColor[i]= 0.1f-cseed*0.9f*(float)(Math.log(cseed)/Math.log(2.0)); 
			greenColor[i]=0.3f;*/ 
			cseed+=step; 
		}
		
		
		// Calcul des angles
		double u[]={1+1/a+b/a,1+1/a+1/b,1+1/b+a/b,1+a+a/b,1+a+b,1+b+b/a};
		double theta[]={Math.acos((u[0]-b/(a*a))/(u[0]+b/(a*a))),
						Math.acos((u[1]-1/(a*b))/(u[1]+1/(a*b))),
						Math.acos((u[2]-a/(b*b))/(u[2]+a/(b*b))),
						Math.acos((u[3]-a*a/b)/(u[3]+a*a/b)),
						Math.acos((u[4]-a*b)/(u[4]+a*b)),
						Math.acos((u[5]-b*b/a)/(u[5]+b*b/a))
		};
	
		
		double radiusCoef[]={b/a,1.0/a,1.0/b,a/b,a,b};
		int modifa[]={-1,-1,0,1,1,0};
		int modifb[]={1,0,-1,-1,0,1};
		
		
		double rotationAngle[]=new double[6];
		rotationAngle[0]=Math.PI-(theta[0]+theta[1]+theta[2]); 
		rotationAngle[1]=Math.PI-(theta[1]+theta[2]+theta[3]); 
		rotationAngle[2]=Math.PI-(theta[2]+theta[3]+theta[4]);
		rotationAngle[3]=Math.PI-(theta[3]+theta[4]+theta[5]); 
		rotationAngle[4]=Math.PI-(theta[4]+theta[5]+theta[0]); 
		rotationAngle[5]=Math.PI-(theta[5]+theta[0]+theta[1]); 
		
		
		
		Polygon background=new Polygon(new int[]{0,0,X,Y},new int[]{0,X,Y,0},4);
		primeIP.setColor(Color.WHITE);
		
		primeIP.fillPolygon(background);
		
		
		primeIP.setFont(new Font(null,Font.ITALIC,60));
		//primeIP.setColor(Color.WHITE);
		primeIP.setLineWidth(5); 
		
		//primeIP.moveTo(150,80); 
		//primeIP.drawString("a="+a+"\n"+"b="+b+"\n"+"n="+n+"\n"+"m="+m);
	
		setProcessor("Verifying", primeIP);
		/*******************************************************/
		DoyleCircle init=new DoyleCircle(0.5,0.5,0,r,0,0); // 0.07
		
		drawCircle(init); 
		
		
		for(int i=0;i<10;i++){
			double theta0=init.getRotation(); 
			double rad1=init.getRadius()*(1+radiusCoef[4]); 
			double nX1=init.getXcenter()+rad1*Math.cos(theta0);
			double nY1=init.getYcenter()+rad1*Math.sin(theta0);
			double angle1=init.getRotation()+rotationAngle[4]; 
			int ca=init.getApower(); 
			int cb=init.getBpower(); 
			DoyleCircle c1=new DoyleCircle(nX1,nY1,angle1,init.getRadius()*radiusCoef[4],
					ca+modifa[4],cb+modifb[4]); 
			drawCircle(c1); 
			init=c1; 
		}
		
		
		
		show();
	}	
}
	
	
	